package com.atguigu.gmall.payment.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.mapper.PaymentInfoMapper;
import com.atguigu.gmall.payment.service.api.PaymentService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;

/**
 * @author: 封捷
 * @create-date: 2022/9/14 9:54
 */
@Service
public class PaymentServiceImpl implements PaymentService {

    @Autowired
    private PaymentInfoMapper paymentInfoMapper;

    @Autowired
    private AlipayClient alipayClient;

    @Override
    public PaymentInfo getPaymentInfoByIdAndType(Long orderId, String paymentType) {
        return paymentInfoMapper
                .selectOne(
                        new QueryWrapper<PaymentInfo>()
                                .eq("order_id", orderId)
                                .eq("payment_type", paymentType));
    }

    @Override
    @Transactional
    public PaymentInfo savePaymentInfo(OrderInfo orderInfo, String paymentType) {

        // 1、构造 PaymentInfo 对象
        PaymentInfo paymentInfo = new PaymentInfo();

        // 2、通过 OrderInfo 对象和 paymentType 给 PaymentInfo 对象设置属性值
        paymentInfo.setOutTradeNo(orderInfo.getOutTradeNo());
        paymentInfo.setOrderId(orderInfo.getId());
        paymentInfo.setPaymentType(paymentType);
        paymentInfo.setTotalAmount(orderInfo.getTotalAmount());
        paymentInfo.setSubject(orderInfo.getTradeBody());
        paymentInfo.setPaymentStatus(PaymentStatus.UNPAID.name());
        paymentInfo.setCreateTime(new Date());

        // 3、执行保存操作
        paymentInfoMapper.insert(paymentInfo);

        return paymentInfo;
    }

    @Override
    public PaymentInfo getPaymentInfoByOutTradeNo(String outTradeNo, String paymentType) {
        return paymentInfoMapper
                .selectOne(
                        new QueryWrapper<PaymentInfo>()
                                .eq("out_trade_no", outTradeNo)
                                .eq("payment_type", paymentType));
    }

    @Override
    public void updatePaymentInfoByCallback(
            String outTradeNo,
            String paymentType,
            Map<String, String> paramsMap) {
        // 1、创建空的 PaymentInfo 对象
        PaymentInfo paymentInfo = new PaymentInfo();

        // 2、把参数设置到空对象中
        paymentInfo.setTradeNo(paramsMap.get("trade_no"));
        paymentInfo.setPaymentStatus(PaymentStatus.PAID.name());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(paramsMap.toString());

        // 3、执行更新
        paymentInfoMapper.update(
                paymentInfo,
                new QueryWrapper<PaymentInfo>()
                        .eq("out_trade_no", outTradeNo)
                        .eq("payment_type", paymentType));
    }

    @Override
    public void updatePaymentInfoStatus(PaymentInfo paymentInfo) {
        paymentInfoMapper.updateById(paymentInfo);
    }

    @Override
    public boolean queryAliPayTradeExists(String outTradeNo) {

        try {
            // 1、创建调用支付宝接口的请求对象
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

            // 2、把需要发送给支付宝的请求参数封装到 JSON 对象中
            JSONObject bizContent = new JSONObject();

            bizContent.put("out_trade_no", outTradeNo);

            request.setBizContent(bizContent.toString());

            // 3、执行请求获取响应对象
            AlipayTradeQueryResponse response = alipayClient.execute(request);

            // 4、返回调用结果
            return response.isSuccess();
        } catch (AlipayApiException e) {
            e.printStackTrace();

            // 5、万一抛异常后进入 catch 块则返回 false 表示调用失败
            return false;
        }
    }

    @Override
    public boolean closeAliPayTrade(String outTradeNo) {

        try {
            // 1、创建调用支付宝接口的请求对象
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();

            // 2、封装发送请求的请求参数
            JSONObject bizContent = new JSONObject();

            bizContent.put("out_trade_no", outTradeNo);

            request.setBizContent(bizContent.toString());

            // 3、执行请求得到相应对象
            AlipayTradeCloseResponse response = alipayClient.execute(request);

            // 4、返回调用结果
            return response.isSuccess();
        } catch (AlipayApiException e) {
            e.printStackTrace();

            // 5、万一抛异常后进入 catch 块则返回 false 表示调用失败
            return false;
        }
    }

    @Override
    public void closePaymentInfo(Long orderId) {

        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setPaymentStatus(PaymentStatus.ClOSED.name());

        paymentInfoMapper.update(
                paymentInfo,
                new QueryWrapper<PaymentInfo>()
                        .eq("order_id", orderId)
                        .eq("payment_type", PaymentType.ALIPAY));
    }
}
